﻿using PaperMaster.Chess.CardSpace;
using PaperMaster.Chess.ChessModel;
using PaperMaster.Chess.Enemy;
using PaperMaster.Chess.PlayerCore;
using PaperMaster.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace PaperMaster.Info
{
    /// <summary>
    /// 该类用于承载各类需要更新的信息便于提取，相当于一个中间人
    /// </summary>
    public abstract class AbstractFightInfoModel
    {
        /// <summary>
        /// 需要更新的UI
        /// </summary>
        public Dictionary<string, GameObject> objs;

        IPlayerCoreModel _playerCoreModel;
        public IPlayerCoreModel playerCoreModel
        {
            get
            {
                if (_playerCoreModel == null)
                {
                    _playerCoreModel = ModelContainer.Get<IPlayerCoreModel>();
                }
                return _playerCoreModel;
            }
        }

        IChessModel _chessModel;
        public IChessModel chessModel
        {
            get
            {
                if (_chessModel == null)
                {
                    _chessModel = ModelContainer.Get<IChessModel>();
                }
                return _chessModel;
            }
        }

        IEnemyModel _enemyModel;
        public IEnemyModel enemyModel
        {
            get
            {
                if (_enemyModel == null)
                {
                    _enemyModel = ModelContainer.Get<IEnemyModel>();
                }
                return _enemyModel;
            }
        }

        ICardModel _cardModel;
        public ICardModel cardModel
        {
            get
            {
                if (_cardModel == null)
                {
                    _cardModel = ModelContainer.Get<ICardModel>();
                }
                return _cardModel;
            }
        }

        public AbstractFightInfoModel()
        {
            Init();
        }
        /// <summary>
        /// 获取各类_obj并进行初始化
        /// </summary>
        protected virtual void Init()
        {
            this.objs = new Dictionary<string, GameObject>();
            GameObject[] objs = GameObject.FindGameObjectsWithTag("FightInfo");
            foreach (var obj in objs)
            {
                this.objs.Add(obj.name, obj);
            }
        }
    }
    public class TestFightInfoModel : AbstractFightInfoModel
    {
        public TestFightInfoModel() : base()
        {

        }
    }
    public abstract class AbstractFightInfoController
    {
        public AbstractFightInfoModel model;
        /// <summary>
        /// 更新函数
        /// </summary>
        public Dictionary<string, Action> updates;
        public AbstractFightInfoController()
        {
            model = new TestFightInfoModel();
            updates = new Dictionary<string, Action>();
            updates.Add("Hp", UpdateHp);
            updates.Add("Mana", UpdateMana);
            updates.Add("Block", UpdateBlock);
            updates.Add("Discard", UpdateDiscard);
            updates.Add("Draw", UpdateDraw);
            updates.Add("Hand", UpdateHand);
            updates.Add("OpponentHp", UpdateOpponentHp);
        }
        public void UpdateUI(string name)
        {
            if (updates.ContainsKey(name))
            {
                updates[name].Invoke();
            }
        }
        public void UpdateUI()
        {
            foreach(var str in model.objs)
            {
                UpdateUI(str.Key);
            }
        }
        #region
        protected abstract void UpdateHp();
        protected abstract void UpdateMana();
        protected abstract void UpdateBlock();
        protected abstract void UpdateDiscard();
        protected abstract void UpdateTip();
        protected abstract void UpdateOpponentHp();
        protected abstract void UpdateDraw();
        protected abstract void UpdateHand();
        #endregion
    }
    public class TestFightInfoController : AbstractFightInfoController
    {
        public TestFightInfoController() : base()
        {

        }

        protected override void UpdateBlock()
        {
            Text text = model.objs["Block"].GetComponent<Text>();
            string str = "";
            ChessBlockModel chessBlock = model.chessModel.Board.selectedBlock;
            if (chessBlock != null)
            {
                str = "元素:" + chessBlock.EleType.ToString();
                if (chessBlock.Piece != null)
                {
                    str += "\n棋子:" + chessBlock.Piece.model.pieceType.ToString();
                    str += "\n棋子主人:" + chessBlock.Piece.model.owner.ToString();
                    str += "\n棋子属性:" + chessBlock.Piece.model.elementType.ToString();
                    str += "\n棋子血量:" + chessBlock.Piece.model.hp;
                    str += "\n棋子攻击:" + chessBlock.Piece.model.atk;
                }
            }
            text.text = str;
        }

        protected override void UpdateDiscard()
        {
            Text text = model.objs["Discard"].GetComponent<Text>();
            text.text = model.cardModel.discardPile.Count.ToString();
        }

        protected override void UpdateDraw()
        {
            Text text = model.objs["Draw"].GetComponent<Text>();
            text.text = model.cardModel.drawPile.Count.ToString();
        }

        protected override void UpdateHand()
        {
            GameObject grid = model.objs["Hand"];
            for(int i = 0; i < 10; i++)
            {
                Transform slot = grid.transform.GetChild(i);
                slot.Find("Title").GetComponent<Text>().text = "";
                slot.Find("Description").GetComponent<Text>().text = "";
            }

            MyList<CardControllerBase> cards = model.cardModel.hand;
            int index = 0;
            foreach(var card in cards)
            {
                Transform slot = grid.transform.GetChild(index++);
                slot.Find("Title").GetComponent<Text>().text = card.model.cardType.ToString();
                slot.Find("Description").GetComponent<Text>().text = card.model.description;
            }
        }

        protected override void UpdateHp()
        {
            Text text = model.objs["Hp"].GetComponent<Text>();
            text.text = model.playerCoreModel.hp.ToString();
        }

        protected override void UpdateMana()
        {
            Text text = model.objs["Mana"].GetComponent<Text>();
            text.text = model.playerCoreModel.mana.ToString();
        }

        protected override void UpdateOpponentHp()
        {
            Text text = model.objs["OpponentHp"].GetComponent<Text>();
            text.text = model.enemyModel.currentEnemy.model.hp.ToString();
        }

        protected override void UpdateTip()
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// 该类用于更新战斗中给玩家显示的各类信息
    /// </summary>
    public abstract class AbstractFightInfoViewController : MonoBehaviour
    {
        public AbstractFightInfoController controller;
        public static AbstractFightInfoController GetController()
        {
            GameObject fightInfoObj = GameObject.Find("FightInfo");
            if (fightInfoObj == null)
            {
                return null;
            }
            return fightInfoObj.GetComponent<AbstractFightInfoViewController>().controller;
        }
        protected abstract void Init();
 
        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}
